package com.aratek.huwai.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aratek.huwai.common.JsonArrayBuilder;
import com.aratek.huwai.common.JsonObjectBuilder;
import com.aratek.huwai.common.R;
import com.aratek.huwai.dao.DishRepository;
import com.aratek.huwai.dao.ProgramRepository;
import com.aratek.huwai.dao.ProgramScoreRepository;
import com.aratek.huwai.dao.ScoreRepository;
import com.aratek.huwai.model.DishEntity;
import com.aratek.huwai.model.ProgramEntity;
import com.aratek.huwai.model.ProgramScoreEntity;
import com.aratek.huwai.model.ScoreEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;

/**
 * @Author 姜寄羽
 * 获取评分结果
 * @Date 2018/1/22 11:59
 */

@RestController
@RequestMapping("/admin")
public class AdminController {

    @Autowired
    DishRepository dishRepository;
    @Autowired
    ScoreRepository scoreRepository;

    @Autowired
    ProgramScoreRepository programScoreRepository;
    @Autowired
    ProgramRepository programRepository;


    @RequestMapping(value = "program_info",method = RequestMethod.GET)
    public R programInfo() throws InterruptedException {
        Thread.sleep(3000);
        R res = R.ok();
        Iterable<ProgramEntity> programEntityIterable = programRepository.findAll();
        JsonArrayBuilder scoreRes = JsonArrayBuilder.create();
        for(ProgramEntity programEntity : programEntityIterable) {
            List<ProgramScoreEntity> scores = programScoreRepository.findByProgramId(programEntity.getId());
            if(scores.size()<3){
                continue;
            }
            IntSummaryStatistics tasteStat = scores.stream().mapToInt(ProgramScoreEntity::getScore).summaryStatistics();
            toScoreRes(scoreRes, programEntity, scores, tasteStat);
        }
        scoreRes.sort((o1, o2) -> {
            JSONObject j1 = (JSONObject)o1;
            JSONObject j2 = (JSONObject)o2;
            return (int) (j2.getDouble("avg")*100-(j1.getDouble("avg")*100));
        });
        res.put("scoreRes", scoreRes);
        return res;
    }

    private void toScoreRes(JsonArrayBuilder scoreRes, ProgramEntity programEntity, List<ProgramScoreEntity> scores, IntSummaryStatistics tasteStat) {
        NumberFormat nt = NumberFormat.getInstance();
        nt.setMinimumFractionDigits(2);
        StringBuilder from = new StringBuilder();
        String prefix = "";
        for (ProgramScoreEntity entity : scores){
            from.append(prefix).append(entity.getRaterId());
            prefix = ",";
        }
        JSONObject taste = JsonObjectBuilder.create().put("max", tasteStat.getMax())
                .put("min",tasteStat.getMin())
                .put("avg",nt.format((double)(tasteStat.getSum() - tasteStat.getMax() - tasteStat.getMin())/(scores.size()-2)))
                .put("name",programEntity.getName()).put("scoreCount",scores.size())
                .put("from",from.toString()).toJSON();
        scoreRes.addNew(taste);
    }

    /**
     * 统计结果
     * @return
     */
    @RequestMapping(value = "info",method = RequestMethod.GET)
    public R info() throws InterruptedException {
        Thread.sleep(3000);
        //计算最终得分
        R res = R.ok();
        Iterable<DishEntity> dishes = dishRepository.findAll();
        res.put("totalDish", dishRepository.count());
        JsonArrayBuilder tasteRes = JsonArrayBuilder.create();
        JsonArrayBuilder exteriorRes = JsonArrayBuilder.create();
        JsonArrayBuilder originalityRes = JsonArrayBuilder.create();

        for(DishEntity dish : dishes) {
            List<ScoreEntity> scores = scoreRepository.findScoreEntitiesByDishId(dish.getId());
            if(scores.size()<3){
                continue;
            }
            IntSummaryStatistics tasteStat = scores.stream().mapToInt(ScoreEntity::getTaste).summaryStatistics();
            toScoreRes(tasteRes, dish, scores, tasteStat);
            IntSummaryStatistics exteriorStat = scores.stream().mapToInt(ScoreEntity::getExterior).summaryStatistics();
            toScoreRes(exteriorRes, dish, scores, exteriorStat);
            IntSummaryStatistics originalityStat = scores.stream().mapToInt(ScoreEntity::getOriginality).summaryStatistics();
            toScoreRes(originalityRes, dish, scores, originalityStat);
        }
        res.put("tasteRes", tasteRes);
        res.put("exteriorRes", exteriorRes);
        res.put("originalityRes", originalityRes);

        JSONObject tasteFavor = findMax(tasteRes);
        JSONObject exteriorFavor = findMax(exteriorRes);
        JSONObject originalityFavor = findMax(originalityRes);
        res.put("tasteFavor", tasteFavor == null ? new JSONObject() : tasteFavor);
        res.put("exteriorFavor", exteriorFavor == null ? new JSONObject() : exteriorFavor);
        res.put("originalityFavor", originalityFavor == null ? new JSONObject() : originalityFavor);
        return res;
    }

    private void toScoreRes(JsonArrayBuilder res, DishEntity dish, List<ScoreEntity> scores, IntSummaryStatistics tasteStat) {
        NumberFormat nt = NumberFormat.getInstance();
        nt.setMinimumFractionDigits(2);
        StringBuilder from = new StringBuilder();
        String prefix = "";
        for (ScoreEntity entity : scores){
            from.append(prefix).append(entity.getRaterTable());
            prefix = ",";
        }
        JSONObject taste = JsonObjectBuilder.create().put("max", tasteStat.getMax())
                .put("min",tasteStat.getMin())
                .put("avg",nt.format((double)(tasteStat.getSum() - tasteStat.getMax() - tasteStat.getMin())/(scores.size()-2)))
                .put("name",dish.getName()).put("table",dish.getTable()).put("scoreCount",scores.size())
                .put("from",from.toString()).toJSON();
        res.addNew(taste);
    }

    private JSONObject findMax(JSONArray array){
        JSONObject res = null;
        for (Object object : array){
            JSONObject item = (JSONObject) object;
            if(res == null || bigger(item.getString("avg"),res.getString("avg"))){
                res = item;
            }
        }
        return res;
    }

    private boolean bigger(String avg1,String avg2){
        return Double.valueOf(avg1) > Double.valueOf(avg2);
    }

    /**
     * 删除指定菜单
     * @return
     */
    @Transactional
    @RequestMapping(value = "removeDish",method = RequestMethod.POST)
    public R removeDish(@RequestBody DishEntity dishEntity){
        int res = dishRepository.deleteDishEntitiesByTableEquals(dishEntity.getTable());
        return R.ok("删除数量"+res);
    }

    /**
     *
     * @return
     */
    @Transactional
    @RequestMapping(value = "removeScore",method = RequestMethod.POST)
    public R removeScore(@RequestBody ScoreEntity scoreEntity){
        int res = scoreRepository.deleteScoreEntitiesByDishIdEqualsAndAndRaterTableEquals
                (scoreEntity.getDishId(),scoreEntity.getRaterTable());
        return R.ok("删除数量"+res);
    }

    @Transactional
    @RequestMapping(value = "removeAll",method = RequestMethod.POST)
    public R initSys(){
        scoreRepository.deleteAll();
        dishRepository.deleteAll();
        return R.ok("完成！");
    }

    @Transactional
    @RequestMapping(value = "removeAllProgram",method = RequestMethod.POST)
    public R initSysProgram(){
        programScoreRepository.deleteAll();
        programRepository.deleteAll();
        return R.ok("完成");
    }
}
